﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;

namespace IMDBApi.Contracts
{
    /// <summary>
    ///     A class which provides all the functions to interact with the movie/series features of the IMDb iPhone API.
    /// </summary>
    public class IMDBMovie : IMDBBase
    {
        /// <summary>
        ///     A title ID (tt0000000)
        /// </summary>
        protected string _titleId;

        #region Constructor

        /// <summary>
        ///     Constructor method.
        /// </summary>
        /// <param name="url">A IMDb URL (e.g. www.imdb.com/title/tt0499549/, tt0499549)</param>
        public IMDBMovie(string url)
        {
            if (url == string.Empty)
            {
                throw new Exception(MethodBase.GetCurrentMethod().Name + ": A IMDb URL is required.");
            }

            string titleId = GetTitleIdFromUrl(url);
            _titleId = titleId;
        }

        #endregion

        #region Public

        /// <summary>
        ///     Get a parsed title ID from an IMDb URL.
        /// </summary>
        /// <param name="url">an IMDb URL.</param>
        /// <returns>Returns parsed title ID.</returns>
        public string GetTitleIdFromUrl(string url)
        {
            Match match = Regex.Match(url, "tt[0-9]{7}", RegexOptions.IgnoreCase);

            if (match.Success)
            {
                return match.Value;
            }

            throw new Exception(MethodBase.GetCurrentMethod().Name + ": Invalid title ID.");
        }

        /// <summary>
        ///     Return the current title ID.
        /// </summary>
        /// <returns>Returns current title ID</returns>
        public string GetTitleId()
        {
            return _titleId;
        }

        /// <summary>
        ///     Get the maindetails for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetMainDetails()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/maindetails", arg);
        }

        /// <summary>
        ///     Get the photo urls for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetPhotos()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/photos", arg);
        }

        /// <summary>
        ///     Get the plot summary for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetPlotSummary()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/plot", arg);
        }

        /// <summary>
        ///     Get the synopsis for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetSynopsis()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/synopsis", arg);
        }

        /// <summary>
        ///     Get the complete cast & crew list for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetFullCredits()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/fullcredits", arg);
        }

        /// <summary>
        ///     Get the external review url list for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetExternalReviews()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/external_reviews", arg);
        }

        /// <summary>
        ///     Get the user review url list for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetUserReviews()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/usercomments", arg);
        }

        /// <summary>
        ///     Get the parental guide for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetParentalGuide()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/parentalguide", arg);
        }

        /// <summary>
        ///     Get the trivia for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetTrivia()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/trivia", arg);
        }

        /// <summary>
        ///     Get the quotes for a movie/series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetQuotes()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/quotes", arg);
        }

        /// <summary>
        ///     Get a episode list sorted by season for a specified series formatted as a JSON string.
        /// </summary>
        /// <returns>JSON formatted string.</returns>
        public string GetEpisodesBySeason()
        {
            var arg = new Dictionary<string, string> {{"tconst", GetTitleId()}};
            return MakeRequest("/title/episodes", arg);
        }

        #endregion
    }
}